/**
 *  FPUStack.java : IceBird project
 *  19:40:11 
 */
package icebird.compiler.ncomp.vs;

import icebird.compiler.ncomp.X86Assembler;
import icebird.compiler.ncomp.X86Register;
import icebird.compiler.ncomp.X86Register.FPU;

/**
 * @author Sergey Shulepoff[Knott]
 */
public final class FPUStack extends ItemStack {
	
	private static FPU[] REGS = new FPU[] {
		FPU.ST0, FPU.ST1,
		FPU.ST2, FPU.ST3,
		FPU.ST4, FPU.ST5,
		FPU.ST6, FPU.ST7,
	};
	
	/**
	 * Get register attached to item.
	 * @return FPU
	 */
	public FPU getRegister(Item i) {
		for (int j = 0; j < peek; j++) {
			if (stack[peek - (j + 1)] == i) {
				return REGS[j];
			}
		}
		
		throw new IllegalStateException();
	}
	
	/**
	 * Get item by register.
	 * @return Item
	 */
	public Item getItem(FPU fp) {
		int idx = peek - (fp.getNumber() + 1);
		return stack[idx];
	}
	
	/**
	 * Swap ST0 with register.
	 * @return void
	 */
	public void xchg(FPU fpu) {
        int idx1 = peek-1;
        int idx2 = peek-(fpu.getNumber() + 1);
        
        Item tmp = stack[idx1];
        stack[idx1] = stack[idx2];
        stack[idx2] = tmp;
	}
	
	/**
	 * Move item to top.
	 * @return void
	 */
	public static void fxch(FPUStack s, Item i) {
		if (s.getPeek() != i) {
			fxch(s, s.getRegister(i));
		}
	}
	
	/**
	 * Move item to top.
	 * @return void
	 */
	public static void fxch(FPUStack s, FPU fp) {
		if (fp == X86Register.ST0) {
			throw new IllegalStateException("Cannot fxch ST0");
		}
		
		X86Assembler asm = X86Assembler.getAsm();
		
		asm.fxch(fp);
		s.xchg(fp);
	}
}
